/**
 * 04-生成蛇
 *蛇的组成:
 * 1.蛇由四个小方块组成的
 * 2.每个小方块有自己的宽高  颜色  坐标 位置xy
 * 3.每个小方块共有的数据是宽高
 */

;(function(win){
    // 9. 定义一个对象来存储蛇移动的方向,这个方向只能访问，不能修改
    var DIRECTION = Object.create(Object.prototype,{
        LEFT:{
            value:1
        },
        TOP:{
            value:2
        },
        RIGHT:{
            value:3
        },
        BOTTOM:{
            value: 4
        }
    });

    //0.获取传入的对象
    var document = win.document; // 获取document对象
    var map = document.querySelector(".map"); // 获取地图盒子对象
    //1.创建蛇的构造函数
    function Snake(params){
        params = params ||{};// 短路运算,检测用户是否传入了真实的对象
        this.width = params.width || 40;
        this.height = params.height || 40;
        this.body = [];// 这个数组是用来存储蛇的各自数据的,比如颜色和坐标
        this.direction = params.direction || DIRECTION.RIGHT; // 10 加了一个默认的移动方向
        this.body[0] = { // 第一个盒子的位置和颜色数据
            x:160,
            y:40,
            color:'#f00'
        };
        this.body[1]={// 第二个盒子的位置和颜色数据
            x:120,
            y:40,
            color:"#fff"
        };
        this.body[2]={// 第三个盒子的位置和颜色数据
            x:80,
            y:40,
            color:"#fff"
        };
        this.body[3]={ // 第四个盒子的位置和颜色数据
            x:40,
            y:40,
            color:"#fff"
        };

        // 6. 重新定义一个新的属性,是用来存储组成蛇的小方块  this.body里面仅仅是一些数据
        this.elements = [];// 重新定义一个新的属性,是用来存储蛇中的小方块的

        // 3. 在构造函数中调用this.create() 为了在其它地方一new 的时候就要创建小方块蛇
        this.create(map);
    }

    // 2. 写创建蛇的方法
    Snake.prototype.create = function (map){
        // 2.1 根据this.body这个数组中的数据来动态的创建小方块
        // 蛇是由四个小方块组成的
        // var arr = this.body;
        for(var i=0;i<this.body.length;i++){
            var divSnake = document.createElement("div");
            divSnake.style.width = this.width +'px';
            divSnake.style.height = this.height + 'px';
            divSnake.style.left = this.body[i].x + 'px';
            divSnake.style.top = this.body[i].y + 'px';
            divSnake.style.backgroundColor = this.body[i].color;

            // 7. 将生成的小方块存到this.elements这个数组当中,就是整个蛇
            this.elements.push(divSnake);

            // 2.2 将创建出来的小方块追加到map当中
            map.appendChild(divSnake)
        }
    };

    //5. 让蛇向前移动
    Snake.prototype.move = function(){
// 5.1 蛇向前移动的原理,蛇头单独的移动，所以先判断蛇身
        // 蛇身的判断,是先让最后一个小方块向前移动一个方格,就是要移动到前一个小方块的坐标位置
        // var arr = this.body
        // 因为每一个小方块都要移动到之前的小方块的位置,所以使用倒序循环
        for(var i=this.body.length-1;i>0;i--){
            // 让当前的小方块的坐标等于前一个小方块的坐标
            this.body[i].x = this.body[i-1].x;
            this.body[i].y = this.body[i-1].y;

            // 5.2 让小方块根据现有的坐标点进行移动
            this.elements[i].style.left = this.body[i].x + 'px';
            this.elements[i].style.top = this.body[i].y + 'px';
        }

        // 8. 蛇头要单独的移动
        // 8.1 根据方向来设置水平或是垂直的坐标
        switch(this.direction){  // 根据方向来判断
            case 1:
                this.body[0].x -= this.width ;// 让蛇头的坐标水平位置在原有的数据上减去一个小方块的宽度
                break;
            case 2:
                this.body[0].y -= this.height;
                break;
            case 3:
                this.body[0].x += this.width;
                break;
            case 4:
                this.body[0].y += this.height;
                break;
        }
        // 8.2 让蛇头根据新的坐标来进行移动
        this.elements[0].style.left = this.body[0].x + 'px';
        this.elements[0].style.top = this.body[0].y + 'px';
    };

    //9. 添加蛇边长的方法
    Snake.prototype.growth = function(){
      //9.1 获取最后一个小方块的坐标
      var last = this.body[this.body.length-1];
      var block = {
          x: last.x,
          y: last.y,
          color: last.color
      };
      //9.2 将创建的最后一个小方块添加到this.body数据里
        this.body.push(block);
      //9.3 蛇要伸长就是就要添加小方块
        var divSnake = document.createElement("div");
        divSnake.style.width = this.width +'px';
        divSnake.style.height = this.height + 'px';
        divSnake.style.left = block.x + 'px';
        divSnake.style.top = block.y + 'px';
        divSnake.style.backgroundColor = block.color;

        // this.elements里面存储了所有的蛇身小方块
        this.elements.push(divSnake);
        // 将创建的小方块添加 到map当中,才能显示出来蛇身的样子
        map.appendChild(divSnake)
    };

    // 4.把蛇对象挂在window对象中,供外部调用
    win.Snake = Snake;
    //11.把方向变量挂靠到window对象中
    win.DIRECTION = DIRECTION;
})(window);